package edu.scsu.csci.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;


/**
 * <p>	General utilities used by the application.
 * 
 * @author Maqbool Khan
 * @since jdk 1.5
 * @see
 */
public class Utilities 
{
	/**
     * Retrieves all classes within a package.
     * 
     * @param pckgname
     * @return Array of full qualified class names from this package.
     */
    public static String[] find(final String pckgname) {
        List<String> classes = new ArrayList<String>();
        String name = new String(pckgname);
        if (!name.startsWith("/")) {
            name = "/" + name;
        }
        name = name.replace('.', File.separatorChar);
        String directoryPath = getAbsolutePath(ReflectionUtil.class) + name;
        final File directory = new File(directoryPath);
        if (directory.exists()) {
            final String[] files = directory.list();
            for (int i = 0; i < files.length; i++) {
                if (files[i].endsWith(".java")) {
                    classes.add(pckgname + "." + files[i].substring(0, files[i].length() - 5));
                }
            }
        }
        return classes.toArray(new String[classes.size()]);
    }
	
	/**
	 * Returns the absolute path for the source code.
	 * 
	 * @param clazz
	 * @return
	 */
	public static String getAbsolutePath(final Class clazz)	{
		ProtectionDomain pd =	clazz.getProtectionDomain();
		CodeSource cs = pd == null ? null : pd.getCodeSource();
		URL url = cs == null ? null : cs.getLocation();
		File f = url == null ? null : new File( url.getFile());
		return f == null ? null : f.getAbsolutePath();
	}
	
	/**
	 * @param url
	 * @return
	 */
	public static String getClassName(String url)	{
		String[] s = url.split(":");
		return s[0];
	}
	
	/**
	 * @param url
	 * @return
	 */
	public static String getMethodName(String url)	{
		String[] s = url.split(":");
		return s[1];
	}
	
	/**
	 * @param url
	 * @param servletContext
	 * @return
	 * @throws IOException
	 */
	public static InputStream getResourceInputStream(String url, ServletContext servletContext) throws IOException {
		if (!isRemote(url)) {
			if (!url.startsWith("/"))
				url = "/" + url;
			InputStream is = servletContext.getResourceAsStream(url);
			if (is == null)
				throw new IOException("Can't open " + url);
			return is;
		}
		else {
			return new URL(url).openStream();
		}
	}
	
	/** Return the URL of the root of the current application
	 */
	public static String getURLToApplication(HttpServletRequest request) {
		return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
	}
      

	/**
	 * Returns true if given string is blank.
	 * 
	 * @param s	String to checked.
	 * @return 	true if String is null or "" else otherwise.
	 */
	public static boolean isEmpty(String s)	{
		return s != null && "".equals(s.trim());
	}
    
	/**
	 * Returns true if the array is null or empty else otherwise.
	 * 
	 * @param array
	 * @return
	 */
	public static boolean isNullOrEmpty(Object[] array) {
		return array == null || array.length <= 0;
	}	
	
	/**
	 * Returns true if given string is null or blank.
	 * @param s	String to checked.
	 * @return 	true if String is null or "" else otherwise.
	 */
	public static boolean isNullOrEmpty(String s)	{
		return s == null || "".equals(s.trim());
	}
	
	private static boolean isRemote(String url) {
		try {
			URL confUrl = new URL(url);
			return confUrl!=null;
		}
		catch (MalformedURLException ex) {
			return false;
		}
	}
		    
}
